package io.github.junxworks.qt.modules.mm.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.collect.Sets;

import io.github.junxworks.ep.auth.model.UserModel;
import io.github.junxworks.ep.core.exception.BusinessException;
import io.github.junxworks.ep.sys.constants.RecordStatus;
import io.github.junxworks.junx.core.util.StringUtils;
import io.github.junxworks.qt.modules.mm.dto.MmModelCondition;
import io.github.junxworks.qt.modules.mm.dto.MmModelDto;
import io.github.junxworks.qt.modules.mm.entity.MmModel;
import io.github.junxworks.qt.modules.mm.entity.MmModelExpRela;
import io.github.junxworks.qt.modules.mm.mapper.MmModelMapper;
import io.github.junxworks.qt.modules.mm.mapper.RuntimeMapper;
import io.github.junxworks.qt.modules.mm.service.MmExpressionService;
import io.github.junxworks.qt.modules.mm.service.MmModelService;
import io.github.junxworks.qt.modules.mm.vo.MmExpressionVo;
import io.github.junxworks.qt.modules.mm.vo.MmModelVo;
import io.github.junxworks.qt.modules.mm.vo.MmVariableVo;

@Service
public class MmModelServiceImpl implements MmModelService {

	@Autowired
	private MmModelMapper mmModelMapper;

	@Autowired
	private RuntimeMapper runtimeMapper;

	@Autowired
	private MmExpressionService expressionService;

	@Override
	public List<MmModelVo> queryList(MmModelCondition condition) {
		return mmModelMapper.queryList(condition);
	}

	@Override
	public MmModelVo queryMmModelById(Long id) {
		return mmModelMapper.queryMmModelById(id);
	}

	@Override
	public void save(MmModelDto dto) {
		if (StringUtils.notNull(dto.getModelName())) {
			MmModelVo _m = mmModelMapper.queryMmModelByName(dto.getModelName());
			if (_m != null) {
				if (dto.getId() == null || !_m.getId().equals(dto.getId())) {
					throw new BusinessException("已经存在模型名称[" + dto.getModelName() + "]");
				}
			}
		}
		if (StringUtils.notNull(dto.getModelNo())) {
			MmModelVo _m = mmModelMapper.queryMmModelByNo(dto.getModelNo());
			if (_m != null) {
				if (dto.getId() == null || _m.getId() != dto.getId()) {
					throw new BusinessException("已经存在模型编号[" + dto.getModelNo() + "]");
				}
			}
		}
		MmModel entity = new MmModel();
		BeanUtils.copyProperties(dto, entity);
		UserModel user = (UserModel) SecurityUtils.getSubject().getPrincipal();
		Long userId = user.getId();
		if (entity.getId() == null) {
			entity.setCreateTime(new Date());
			entity.setCreateUser(userId);
			entity.setStatus(RecordStatus.NORMAL.getValue());
			mmModelMapper.insertWithoutNull(entity);
		} else {
			MmModel m = mmModelMapper.selectEntityByID(MmModel.class, entity.getId());
			if (!userId.equals(m.getCreateUser())) {
				throw new BusinessException("不是创建者不能操作数据");
			}
			entity.setUpdateTime(new Date());
			entity.setUpdateUser(userId);
			mmModelMapper.updateWithoutNull(entity);
			mmModelMapper.deleteModelExpRelaByModelId(entity.getId());
		}
		if (dto.getExpList() != null) {
			mmModelMapper.insertBatch(dto.getExpList().stream().flatMap(f -> {
				MmModelExpRela r = new MmModelExpRela();
				r.setModelId(entity.getId());
				r.setExpId(f);
				return Stream.of(r);
			}).collect(Collectors.toList()));
		}
	}

	@Override
	public List<MmExpressionVo> queryExpressionsByModelId(Long id) {
		return mmModelMapper.queryExpressionsByModelId(id);
	}

	@Override
	public Set<Long> queryAllDatastreams(List<String> modelNos) {
		List<Long> expIds = mmModelMapper.queryAllExpIds(modelNos);
		if (expIds.isEmpty()) {
			return null;
		}
		return Sets.newHashSet(expressionService.queryAllDatastreamByIds(expIds));
	}

	@Override
	public List<MmVariableVo> queryAllVariables(List<String> modelNos) {
		List<Long> expIds = mmModelMapper.queryAllExpIds(modelNos);
		if (expIds.isEmpty()) {
			return null;
		}
		return expressionService.queryAllVariableByIds(expIds);
	}

	@Override
	public List<MmExpressionVo> queryExpressions(List<String> modelNos) {
		List<Long> expIds = mmModelMapper.queryAllExpIds(modelNos);
		if (expIds.isEmpty()) {
			return null;
		}
		return expressionService.queryAllExpressionsByIds(expIds);
	}

	@Override
	public void clearExeResultsByDate(String tradeDate) {
		runtimeMapper.deleteStatResults(tradeDate);/*新模式下统计数据量大，最好不要删除*/
		runtimeMapper.deleteExpResults(tradeDate);
		runtimeMapper.deleteModelResults(tradeDate);
	}

	@Override
	public List<MmModelVo> queryModels(List<String> modelNos) {
		MmModelCondition condition = new MmModelCondition();
		condition.setModelNos(modelNos);
		return queryList(condition);
	}

}
